home *** CD-ROM | disk | FTP | other *** search
/ Programming Sound Cards / Programming Sound Cards.iso / sound_87 / devfile.pas < prev    next >
Pascal/Delphi Source File  |  1995-01-01  |  8KB  |  340 lines

  1. {****************************************************************************}
  2. {                                                                            }
  3. { MODULE:         DevFile                                                    }
  4. {                                                                            }
  5. { DESCRIPTION:    Device driver for the Adlib sound card and compatibles.    }
  6. {                 This works with Sound Blasters and with Covox SM II.       }
  7. {                 It uses timer polling.                                     }
  8. {                                                                            }
  9. { AUTHOR:         Juan Carlos Arévalo                                        }
  10. {                                                                            }
  11. { MODIFICATIONS:  Nobody (yet ;-)                                            }
  12. {                                                                            }
  13. { HISTORY:        12-Nov-1992 Description                                    }
  14. {                                                                            }
  15. { (C) 1992 VangeliSTeam                                                      }
  16. {____________________________________________________________________________}
  17.  
  18. UNIT DevFile;
  19.  
  20. INTERFACE
  21.  
  22.  
  23.  
  24.  
  25. { Device ID String. }
  26.  
  27. CONST
  28.   FileDevID    = 'File';
  29.   FileDevFName : STRING = 'SBDSP$';
  30.  
  31.  
  32.  
  33.  
  34. FUNCTION FileRun : CHAR;
  35.  
  36.  
  37.  
  38.  
  39. IMPLEMENTATION
  40.  
  41. USES Dos, Kbd, SoundDevices, StrConst;
  42.  
  43.  
  44. VAR
  45.   Fil : FILE;
  46.  
  47.  
  48.  
  49.  
  50. FUNCTION DosDevIOCTL(VAR f; Cat, Func: BYTE; VAR Data) : WORD; ASSEMBLER;
  51.   ASM
  52.           PUSH    DS
  53.  
  54.           MOV     CH,[Cat]
  55.           MOV     CL,[Func]
  56.           LDS     BX,[f]
  57.           MOV     BX,FileRec([DS:BX]).Handle
  58.           LDS     DX,Data
  59.           MOV     AX,$440C
  60.           INT     $21
  61.  
  62.           POP     DS
  63.  
  64.           JC      @@Fin
  65.           XOR     AX,AX
  66. @@Fin:
  67.   END;
  68.  
  69. VAR
  70.   NULL : BYTE ABSOLUTE 0:0;
  71.  
  72.  
  73.  
  74.  
  75.  
  76.  
  77. VAR
  78.   FileBuffer : ARRAY[1..1600] OF BYTE;
  79.   FileDevIdx : WORD;
  80.  
  81.   TimerPos : BYTE ABSOLUTE 0:$46C;
  82.  
  83. CONST
  84.   LastTimerPos : BYTE = 0;
  85.  
  86.  
  87. FUNCTION FilePoll : BOOLEAN; FAR;
  88.   TYPE
  89.     WB = ARRAY[1..32760] OF WORD;
  90.   CONST
  91.     Delay        : WORD = 0;
  92.     Ct           : WORD = 0;
  93.   VAR
  94.     MBuffer  : ^WB ABSOLUTE Sounding;
  95.     i, j     : WORD;
  96.     r        : WORD;
  97.     lim      : WORD;
  98.   BEGIN
  99.  
  100.     FilePoll := TRUE;
  101.  
  102.     IF TimerPos = LastTimerPos THEN EXIT;
  103.  
  104.     LastTimerPos := TimerPos;
  105.  
  106.     INC(Ct, 500);
  107.     lim := Ct DIV 180;
  108.     Ct  := Ct MOD 180;
  109.  
  110.     FOR j := 1 TO lim DO
  111.       BEGIN
  112.         IF DoGetBuffer <> 0 THEN
  113.           BEGIN
  114.  
  115.             IF FileDevIdx + SoundLeft > 1600 THEN
  116.               BEGIN
  117. {
  118.                 DosDevIOCtl(Fil, $80, 3, NULL);
  119.                 DosDevIOCtl(Fil, $80, 0, NULL);
  120. }
  121.                 BlockWrite(Fil, FileBuffer[1], FileDevIdx, r);
  122.                 FileDevIdx := 0;
  123.               END;
  124.  
  125.                 ASM
  126.  
  127.                  MOV    CX,SoundLeft
  128.                  LES    SI,MBuffer
  129.                  MOV    DI,OFFSET FileBuffer
  130.                  MOV    AX,FileDevIdx
  131.                  ADD    DI,AX
  132.  
  133. @@lp:
  134.                  MOV    AX,[ES:SI]
  135.                  ADD    AX,[ES:SI+6]
  136.                  ADD    AX,[ES:SI+8]
  137.                  ADD    AX,[ES:SI+14]
  138.                  ADD    AX,[ES:SI+16]
  139.                  ADD    AX,[ES:SI+22]
  140.                  ADD    AX,[ES:SI+24]
  141.                  ADD    AX,[ES:SI+30]
  142.  
  143.                  MOV    BX,[ES:SI+2]
  144.                  ADD    BX,[ES:SI+4]
  145.                  ADD    BX,[ES:SI+10]
  146.                  ADD    BX,[ES:SI+12]
  147.                  ADD    BX,[ES:SI+18]
  148.                  ADD    BX,[ES:SI+20]
  149.                  ADD    BX,[ES:SI+26]
  150.                  ADD    BX,[ES:SI+28]
  151.  
  152.  
  153.                  ADD    AX,BX
  154.                  JNO    @@nooverf
  155.                  JS     @@posit
  156.                   MOV   AX,-32768
  157.                  JMP    @@nooverf
  158. @@posit:          MOV   AX,32767
  159. @@nooverf:
  160.                  XOR    AH,80h
  161.                  MOV    [DI],AH
  162.                  INC    DI
  163.                  ADD    SI,MaxChannels*2
  164.                  LOOP   @@lp
  165.  
  166.                 END;
  167.  
  168. {
  169.             FOR i := 1 TO SoundLeft DO
  170.               BEGIN
  171.                 FileBuffer[FileDevIdx + i] := HI(MBuffer^[i*4] +
  172.                                                MBuffer^[i*4-1] +
  173.                                                MBuffer^[i*4-2] +
  174.                                                MBuffer^[i*4-3]) XOR 128;
  175.               END;
  176. }
  177.             INC(FileDevIdx, SoundLeft);
  178.             Delay := 0;
  179.           END
  180.         ELSE
  181.           INC(Delay);
  182.  
  183.         PeriodicProc;
  184.         IF Delay > 3 THEN
  185.           BEGIN
  186.             IF FileDevIdx > 0 THEN
  187.               BEGIN
  188.                 BlockWrite(Fil, FileBuffer[1], FileDevIdx, r);
  189.               END;
  190.             FilePoll := FALSE;
  191.             EXIT;
  192.           END;
  193.  
  194.     
  195.       END;
  196.  
  197.     FilePoll := TRUE;
  198.  
  199.   END;
  200.  
  201.  
  202. PROCEDURE DevFilePoll; FAR;
  203.   BEGIN
  204.     FilePoll;
  205.   END;
  206.  
  207.  
  208. FUNCTION FileRun : CHAR;
  209.   VAR
  210.     ch : CHAR;
  211.   BEGIN
  212.  
  213.     FileRun := #0;
  214.  
  215.     WHILE NOT KbdKeyPressed AND FilePoll DO DEC(LastTimerPos);
  216.  
  217.     WHILE KbdKeyPressed DO
  218.       BEGIN
  219.         ch := CHAR(KbdReadKey);
  220.         FileRun := ch;
  221.       END;
  222.  
  223.     DeviceIdling := TRUE;
  224.  
  225.   END;
  226.  
  227.  
  228.  
  229. {----------------------------------------------------------------------------}
  230. { Name function.                                                             }
  231. {____________________________________________________________________________}
  232.  
  233. FUNCTION FileName : TDevName; FAR;
  234.   BEGIN
  235.     FileName := GetString(StrDevFileName);
  236.   END;
  237.  
  238.  
  239.  
  240.  
  241. {----------------------------------------------------------------------------}
  242. { Autodetect routine. It's always present. Well, it's not, but... O:-)       }
  243. {____________________________________________________________________________}
  244.  
  245. FUNCTION DevDetect : BOOLEAN; FAR;
  246.   BEGIN
  247.     DevDetect := TRUE;
  248.   END;
  249.  
  250.  
  251.  
  252.  
  253. {----------------------------------------------------------------------------}
  254. { Device Initialisation routine.                                             }
  255. {____________________________________________________________________________}
  256.  
  257. PROCEDURE DevInit(Hz: WORD); FAR; 
  258.   VAR
  259.     w     : WORD;
  260.   BEGIN
  261.     Assign(Fil, FileDevFName);
  262.     Rewrite(Fil, 1);
  263.  
  264.     w := 0;
  265.  
  266.     DosDevIOCtl(Fil, $80, 1, Hz);
  267.     DosDevIOCtl(Fil, $80, 5, w);
  268.  
  269.     CalcTimerData(Hz);   { Init variables. Shouldn't do it this way, but... }
  270.     FileDevIdx   := 0;
  271.     DeviceIdling := FALSE;
  272.   END;
  273.  
  274.  
  275.  
  276.  
  277. {----------------------------------------------------------------------------}
  278. { Device deinitialisation routine.                                           }
  279. {____________________________________________________________________________}
  280.  
  281. PROCEDURE DevEnd; FAR;
  282.   BEGIN
  283. {
  284.     DosDevIOCtl(Fil, $80, 0, NULL);
  285. }
  286.     Close(Fil);
  287.   END;
  288.  
  289.  
  290.  
  291.  
  292. {----------------------------------------------------------------------------}
  293. { Accesory routines.                                                         }
  294. {____________________________________________________________________________}
  295.  
  296. PROCEDURE DevChgHz(Hz: WORD); FAR;
  297.   BEGIN
  298.     CalcTimerData(Hz);
  299.     DosDevIOCtl(Fil, $80, 0, NULL);
  300.     Close(Fil);
  301.     Rewrite(Fil, 1);
  302.     DosDevIOCtl(Fil, $80, 1, Hz);
  303.   END;
  304.  
  305.  
  306.  
  307.  
  308. {----------------------------------------------------------------------------}
  309. { Device record.                                                             }
  310. {____________________________________________________________________________}
  311.  
  312. CONST
  313.   FileData : TSoundDevice = (
  314.     DevID      : FileDevID;
  315.     DMA        : FALSE
  316.   );
  317.  
  318.  
  319.  
  320.  
  321. {----------------------------------------------------------------------------}
  322. { Init code.                                                                 }
  323. {____________________________________________________________________________}
  324.  
  325. BEGIN
  326.  
  327.   WITH FileData DO BEGIN
  328.     Name            := FileName;
  329.     AutoDetect      := DevDetect;
  330.     InitRut         := DevInit;
  331.     ChgHzProc       := DevChgHz;
  332.     GetRealFreqProc := GetRealFreq;
  333.     PollRut         := DevFilePoll;
  334.     EndRut          := DevEnd;
  335.   END;
  336.  
  337.   InitDevice(@FileData);
  338.  
  339. END.
  340.